package io.github.uicdb.et.client;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;



public class ImageEntityRenderer {

    protected final RenderType TYPE;
    private final onImageRenderer renderer;

    /**
     * @param img          图片资源路径
     * @param renderer     渲染器
     */
    public ImageEntityRenderer(ResourceLocation img, onImageRenderer renderer) {
        this.TYPE = SimpleRenderType.IMAGE.apply(img);
        this.renderer = renderer;
    }

    /**
     * 渲染
     */
    public void render(PoseStack matrixStack, float partialTick, Entity entity) {
        renderOnEntity(matrixStack, partialTick, entity, TYPE, renderer);
    }

    /**
     * 在实体坐标处渲染
     *
     * @param matrixStack     矩阵堆
     * @param partialTick     渲染微型tick
     * @param entity          实体
     * @param renderType      渲染类型
     * @param onLevelRenderer 渲染内容
     */
    public static void renderOnEntity(PoseStack matrixStack, float partialTick, Entity entity, RenderType renderType, onImageRenderer onLevelRenderer) {
        var bufferSource = Minecraft.getInstance().renderBuffers().bufferSource();
        var offset = Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(entity).getRenderOffset(entity, partialTick);
        //线性处理坐标
        float px = (float) (Mth.lerp(partialTick, entity.xOld, entity.getX()) + offset.x);
        float py = (float) (Mth.lerp(partialTick, entity.yOld, entity.getY()) + offset.y);
        float pz = (float) (Mth.lerp(partialTick, entity.zOld, entity.getZ()) + offset.z);

        VertexConsumer builder = bufferSource.getBuffer(renderType);
        matrixStack.pushPose();
        FDRenderHelper.bindMainCameraPos(matrixStack, px, py, pz);
        //render
        onLevelRenderer.onRenderer(matrixStack, builder, partialTick, entity.level());
        matrixStack.popPose();
        bufferSource.endBatch(renderType);
    }

    /**
     * 在x-z平面渲染图片并旋转
     *
     * @param size   直径
     * @param height 高度
     * @param rotY 水平旋转速度
     * @param rotX 垂直旋转速度
     * @param r      红色
     * @param g      绿色
     * @param b      蓝色
     * @param a      透明度
     */
    public static void renderImgAndRot(VertexConsumer buffer, PoseStack stack, float size, float height, int rotY, int rotX,int x,int y,int z,int relativeX,int relativeY,int relativeZ, int r, int g, int b, int a, Level level,int lightmap) {
        float degree_y = 0;
        float degree_x = 0;
        long pGameTime = level.getGameTime();
        if (rotY != 0) {
            float f = (float) Math.floorMod(pGameTime, 360 * rotY);
            degree_y = f / rotY;
        }
        if (rotX != 0) {
            float f = (float) Math.floorMod(pGameTime, 360 * rotX);
            degree_x = f / rotX;
        }
        if (height == 0) {
            height = height + 0.01f;
        }
        //防止穿模
        float half = size / 2f;

        //开始记录变换，避免影响之前渲染
        stack.pushPose();
        stack.translate(x,y+ height, z);
        stack.mulPose(Axis.YP.rotation(degree_y));
        stack.mulPose(Axis.XP.rotation(degree_x));
        stack.translate(relativeX,relativeY,relativeZ);


        //获得变换矩阵
        var matrix = stack.last().pose();
        //以当前坐标为(0,0)点，构建图形
        //构造（-半径，-半径）点，颜色是rgba，uv是0，0
        buffer.addVertex(matrix, -half, 0, -half).setUv(0, 0);
        //以此类推
        buffer.addVertex(matrix, -half, 0, half).setUv(0, 1);
        buffer.addVertex(matrix, half, 0, half).setUv(1, 1);
        buffer.addVertex(matrix, half, 0, -half).setUv(1, 0);
        //结束记录变换
        stack.popPose();
    }

    public interface onImageRenderer {
        void onRenderer(PoseStack poseStack, VertexConsumer buffer, float partialTick, Level level);
    }

}
